# —*— coding = utf-8 -*-
# @Time :2021/11/11   13:41
# @File :shenliu.py
# @Software: PyCharm
'''
////////////////////////////////////////////////////////////////////
//                          _ooOoo_                               //
//                         o8888888o                              //
//                         88" . "88                              //
//                         (| ^_^ |)                              //
//                         O\  =  /O                              //
//                      ____/`---'\____                           //
//                    .'  \\|     |//  `.                         //
//                   /  \\|||  :  |||//  \                        //
//                  /  _||||| -:- |||||-  \                       //
//                  |   | \\\  -  /// |   |                       //
//                  | \_|  ''\---/''  |   |                       //
//                  \  .-\__  `-`  ___/-. /                       //
//                ___`. .'  /--.--\  `. . ___                     //
//              ."" '<  `.___\_<|>_/___.'  >'"".                  //
//            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
//      ========`-.____`-.___\_____/___.-`____.-'========         //
//                           `=---='                              //
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//         佛祖保佑       永无BUG     永不修改                       //
////////////////////////////////////////////////////////////////////
'''
#导入库

from pylab import *
import copy
import sys  # 导入sys模块

sys.setrecursionlimit(300000)  # 将默认的递归深度修改为300000，然而好像没作用，在windows上

#生成矩阵
r = rand(150, 150)
 # r = rand(6, 6)
r_copy = copy.deepcopy(r)

#创建画布
fig,ax = subplots(figsize =(6,6))

b = {}
#用来存放p从0到1的最大团簇的axis
cluster_max_axis ={x:[] for x in range(100)}
#用来存放p从0到1的次大团簇的axis
cluster_max_axis2 ={x:[] for x in range(100)}


#用来存放p从0到1的最大团簇的最大最小xy
cluster_max_info ={x:[] for x in range(99)}
#用来存放p从0到1的次大团簇的最大最小xy
cluster_max_info2 ={x:[] for x in range(99)}

#对矩阵进行一系列操作的函数
def cluster():
    global key1
    key1 = 0
    global key2
    key2 = 0
    sys.setrecursionlimit(300000)
    #p循环
    for n in range(1,100):
        p = n / 100
        # 步长为2？ 但是只能取到147 ，148只能重新循环？
        #将r变成0，1矩阵
        for i in range(0, 150):
            for j in range(0, 150):
                # for i in range(0, 6):
                #     for j in range(0, 6):
                if r_copy[i][j] < p:
                    r[i][j] = 1
                    # x.append(numpy.argwhere(r == 1))
                if r_copy[i][j] >= p:
                    r[i][j] = 0

        key = 2
        #让相同团簇在矩阵中的编号相同
        for i in range(0, 150):
            for j in range(0, 150):
                if r[i][j]==1:
                    matrix_sort(i, j, r, key)#团簇进行分类的函数
                    key += 1
        #寻找出团簇的数量
        global list
        list = []
        for i in range(150):
            for j in range(150):
                list.append(r[i, j])
        max_qty = max(list)

        #sort_dict存放团簇的点的坐标
        global sort_dict
        sort_dict = {x: [] for x in range(4000)}
        for i in range(150):
            for j in range(150):
                if r[i][j] > 1 :
                    sort_dict[r[i][j]].append([i, j])
        #删除空的键值对
        for i in range(len(sort_dict)):
            if len(sort_dict[i]) == 0:
                del sort_dict[i]

        #团簇大小
        global cluster_all
        cluster_all = {}
        for i in sort_dict:
            cluster_all[i] = len(sort_dict[i])
    ##    if n <=0.6:
    ##        print('小于Pc时除最大团簇外的尺寸分布情况:\n',cluster_all)
        num_cluster = 0
        for i in cluster_all:
            num_cluster += cluster_all[i]
        mean_cluster = num_cluster/len(cluster_all)
    ##    print('团簇的平均大小:\n',mean_cluster)
        # 算法最大问题，有两个相同的最大团簇和次大团簇时，只会取到key更大的那一个，已解决


        # 寻找最大团簇
        cluster_max = max(cluster_all.values())
    ##    print('最大团簇大小\n',cluster_max)
        cluster_all[0] = 0
        cluster_all[1] = 0
        for i in range(len(cluster_all)):

            if cluster_all[i] == cluster_max:
                cluster_max_num = i
                #寻找最小和最大的x和y坐标,因为对字典拍过序，所以miny一定是第一个，maxy一定是最后一个
                min_y = sort_dict[i][0][0]
                max_y = sort_dict[i][len(sort_dict[i])-1][0]

                cy = []
                for n in range(len(sort_dict[i])):
                    cy.append(sort_dict[cluster_max_num][n][1])
                min_x = min(cy)
                max_x = max(cy)
                # print('最大最小x和y\n',min_x,min_y,max_x,max_y)
                cluster_max_info[key1].append([min_x,min_y,max_x,max_y])

            #将最大团簇删除，方便后面找次大
        for i in range(len(cluster_all)):
            if cluster_all[i] == cluster_max:
                del cluster_all[i]

    ##    if n >0.6:
    ##        print('大于Pc时的尺寸分布情况:\n',cluster_all)
        
        key1 += 1
        # print(cluster_max_num)
        for i in range(max(cluster_all.keys())):
            if i not in cluster_all.keys():
                cluster_all[i] = 0
        
        
        # 寻找次大团簇
        cluster_max2 = max(cluster_all.values())
    ##    print('次大团簇大小：\n',cluster_max2)
        for i in cluster_all:
            if cluster_all[i] == cluster_max2:
                cluster_max_num = i
                # 寻找最小和最大的x和y坐标,因为对字典拍过序，所以minx一定是第一个，maxx一定是最后一个
                if len(cluster_all) > 2:#排除只有一个团簇的情况
                    # cluster_max_axis
                    # cluster_max_axis2[n].append(sort_dict[i])
                    min_y2 = sort_dict[i][0][0]
                    max_y2 = sort_dict[i][len(sort_dict[i]) - 1][0]

                    global cx
                    cx = []
                    for n in range(len(sort_dict[i])):
                        cx.append(sort_dict[cluster_max_num][n][1])
                    min_x2 = min(cx)
                    max_x2 = max(cx)
        # print('最大最小x和y\n', min_x2, min_y2, max_x2, max_y2)
                    cluster_max_info2[key2].append([min_x2,min_y2,max_x2,max_y2])

        key2 += 1




#用来对矩阵进行团簇分类
def matrix_sort(i,j,r,key):
    r[i, j] = int(key)
    # 上
    if i - 1 >= 0 and r[i - 1, j] == 1:
        matrix_sort(i - 1, j, r, key)
    #上边界
    elif i - 1 < 0 and r[i + 149, j] == 1:
        matrix_sort(i + 149, j, r, key)

    # 下
    if i + 1 < 150 and r[i + 1, j] == 1:
        matrix_sort(i + 1, j, r, key)
    #下边界
    elif i + 1 >= 150 and r[i - 149, j] == 1:
        matrix_sort(i - 149, j, r, key)

    # 右
    if j + 1 < 150 and r[i, j + 1] == 1:
        matrix_sort(i, j + 1, r, key)
    #右边界
    elif j + 1 >= 150 and r[i, j - 149] == 1:
        matrix_sort(i, j - 149, r, key)

    # 左
    if j - 1 >= 0 and r[i, j - 1] == 1:
        matrix_sort(i, j - 1, r, key)
    # 左边界
    elif j - 1 < 0 and r[i, j + 149] == 1:
        matrix_sort(i, j + 149, r, key)

#绘制动态图函数
def draw_gif():
    for n in range(1, 100):
        p = n / 100
        # 步长为2？ 但是只能取到147 ，148只能重新循环？
        # p = 0.4
        for i in range(0, 150):
            for j in range(0, 150):
                # for i in range(0, 6):
                #     for j in range(0, 6):
                if r_copy[i][j] < p:
                    r[i][j] = 1
                    # x.append(numpy.argwhere(r == 1))
                if r_copy[i][j] >= p:
                    r[i][j] = 0

        # 让相同团簇在矩阵中的编号相同
        key = 2
        for i in range(0, 150):
            for j in range(0, 150):
                if r[i][j] == 1:
                    matrix_sort(i, j, r, key)  # 团簇进行分类的函数
                    key += 1

        # sort_dict存放团簇的点的坐标
        global sort_dict
        sort_dict = {x: [] for x in range(4000)}

        for i in range(150):
            for j in range(150):
                if r[i][j] > 1:
                    sort_dict[r[i][j]].append([i, j])

        for i in range(len(sort_dict)):
            if len(sort_dict[i]) == 0:
                del sort_dict[i]

        #团簇大小
        global cluster_all
        cluster_all = {}
        for i in sort_dict:
            cluster_all[i] = len(sort_dict[i])

        #最重要的三行代码 对矩阵从新赋值，团簇越大 值越大，前提是值不为0
        for i in sort_dict:
            for j in range(len(sort_dict[i])):
                r[sort_dict[i][j][0],sort_dict[i][j][1]] = cluster_all[i]

        plt.cla()#清除上一次画的矩形
        
        #绘制最大团簇的框，为红色
        for m in range(len(cluster_max_info[n-1])):
            rect_max = plt.Rectangle((cluster_max_info[n-1][m][0] - 0.5, cluster_max_info[n-1][m][1] - 0.5),
                                 cluster_max_info[n-1][m][2] - cluster_max_info[n-1][m][0] + 1,
                                 cluster_max_info[n-1][m][3] - cluster_max_info[n-1][m][1] + 1,
                                 fill=False, edgecolor='red', linewidth=1)
            ax.add_patch(rect_max)

        #绘制次大团簇的框，为白色
        for m in range(len(cluster_max_info2[n - 1])):
            rect_max2 = plt.Rectangle((cluster_max_info2[n - 1][m][0] - 0.5, cluster_max_info2[n - 1][m][1] - 0.5),
                                     cluster_max_info2[n - 1][m][2] - cluster_max_info2[n - 1][m][0] + 1,
                                     cluster_max_info2[n - 1][m][3] - cluster_max_info2[n - 1][m][1] + 1,
                                     fill=False, edgecolor='white', linewidth=1)

            ax.add_patch(rect_max2)
        # print('r\n',r)
        #绘制 imshow函数绘制矩阵很好用
        imshow(r, origin='upper')
        #标题
        title('p == ' + str(p))
        #暂停时间
        plt.pause(0.05)
if __name__ == "__main__":#开始

    cluster()
    draw_gif()


